import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
/**
 *
 * @ProjectName:    flutter_skeleton
 * @Package:
 * @ClassName:      shimmer_view
 * @Description:    dart文件作用
 * @Author:         孙浩
 * @CreateDate:     4/29/21 3:25 PM
 */

class Shimmer extends StatefulWidget {
  final Widget child;
  final Duration period;
  final Gradient gradient;
  final AnimationController animationController;

  Shimmer(this.animationController,
      {Key key, this.child, this.period, this.gradient})
      : super(key: key);

  @override
  _ShimmerState createState() => _ShimmerState();
}

class _ShimmerState extends State<Shimmer> {
  @override
  void initState() {
    super.initState();

  }

  @override
  Widget build(BuildContext context) {
    return _Shimmer(
      child: widget.child,
      gradient: widget.gradient,
      percent: widget.animationController.value,
    );
  }
}

class _Shimmer extends SingleChildRenderObjectWidget {
  final Gradient gradient;
  final double percent;

  _Shimmer({Widget child, this.gradient, this.percent}) : super(child: child);

  @override
  _ShimmerFilter createRenderObject(BuildContext context) {
    return _ShimmerFilter(gradient, percent);
  }

  @override
  void updateRenderObject(
      BuildContext context, covariant _ShimmerFilter shimmer) {
    shimmer.percent = percent;
  }
}

class _ShimmerFilter extends RenderProxyBox {
  final _clearPaint = Paint();
  final Paint _gradientPaint;
  final Gradient _gradient;
  double _percent;

  _ShimmerFilter(this._gradient, this._percent)
      : _gradientPaint = Paint()..blendMode = BlendMode.srcIn;

  @override
  bool get alwaysNeedsCompositing => child != null;

  set percent(double newValue) {
    if (newValue != _percent) {
      _percent = newValue;
      markNeedsPaint();
    }
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    if (child != null) {
      assert(needsCompositing);

      final width = child.size.width;
      final height = child.size.height;
      Rect rect;
      double dx, dy;

      dx = _offset(-width, width, _percent);
      dy = 0.0;
      rect = Rect.fromLTWH(offset.dx - width, offset.dy, 3 * width, height);

      _gradientPaint.shader = _gradient.createShader(rect);

      context.canvas.saveLayer(offset & child.size, _clearPaint);
      context.paintChild(child, offset);
      context.canvas.translate(dx, dy);
      context.canvas.drawRect(rect, _gradientPaint);
      context.canvas.restore();

    }
  }

  double _offset(double start, double end, double percent) {
    return start + (end - start) * percent;
  }
}
